package com.zegome.game.gomestory;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.Toast;

import com.appota.payment.AppotaPayment;
import com.appota.payment.AppotaPaymentReceiver;
import com.appota.payment.callback.TransactionStatusCallback;
import com.appota.payment.commons.AlertDialogManager;
import com.appota.payment.commons.AppotaAction;
import com.appota.payment.model.CardPaymentResult;
import com.appota.payment.model.TransactionResult;
import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration;
import com.facebook.FacebookException;
import com.facebook.FacebookOperationCanceledException;
import com.facebook.FacebookRequestError;
import com.facebook.HttpMethod;
import com.facebook.Request;
import com.facebook.Request.Callback;
import com.facebook.RequestBatch;
import com.facebook.Response;
import com.facebook.Session;
import com.facebook.Session.StatusCallback;
import com.facebook.SessionState;
import com.facebook.UiLifecycleHelper;
import com.facebook.model.GraphObject;
import com.facebook.widget.WebDialog;
import com.google.ads.AdRequest;
import com.zegome.facebook.CustomLogin;
import com.zegome.facebook.IFacebookEventListener;
import com.zegome.facebook.IFacebookProcessorListener;
import com.zegome.game.gomestory.main.Center;
import com.zegome.game.gomestory.main.D;
import com.zegome.game.gomestory.main.GomeController;
import com.zegome.game.gomestory.main.helper.AdmobControl;
import com.zegome.game.gomestory.main.helper.GiftRequest;
import com.zegome.game.main.AndroidGameController;
import com.zegome.game.main.ZegomeActivity;
import com.zegome.payment.appota.IAppotaPaymentListener;
import com.zegome.payment.appota.IAppotaPaymentProcessorListener;
import com.zegome.payment.appota.ISmsEvent;
import com.zegome.payment.appota.ISmsProcessor;
import com.zegome.payment.appota.SmsCreate;
import com.zegome.payment.google.IGooglePaymentListener;
import com.zegome.secure.ExternalFileEncrypt;

public class MainActivity extends ZegomeActivity implements IFacebookEventListener, IAppotaPaymentListener, ISmsEvent, IGooglePaymentListener{
	
	private static final String TAG = MainActivity.class.getName();
	private static final String PENDING_PUBLISH_KEY = "pendingPublishReauthorization";
	
	private static final String SMS_TEST_NUMBER = "6165";
	private static final String SMS_NUMBER = "6765";
	private static final String SMS_MESSAGE = "NAP 460M";
	
	private static final String GOOGLE_AD = "a1529345c02966d";
	private static final String APPOTA_AD = "a1527cf0286ec5c";
		
	private SmsCreate mSmsCreate;
	private ISmsProcessor mSmsProcessor;
	private IAppotaPaymentProcessorListener mAppotaPaymentProcessor;
	
	private List<String> PERMISSIONS = Arrays.asList("publish_actions");
	private String mRequestId = null;
	
	public static final boolean isGooglePlay = false;
	public final static boolean isMC = false, isAdmob = true;
	
	private String mSmsNumber = null;
	
	private CustomLogin mCustomLogin;
	private StatusCallback mCallback = new StatusCallback() {
	
		@Override
		public void call(Session session, SessionState state, Exception exception) {
			if (isPause) return;
			onSessionStateChange(session, state, exception);
		}
	};
	
	private UiLifecycleHelper mUiLifecycleHelper;

	private ProgressDialog progressDialog;
	
	private IFacebookProcessorListener mFBProcessorListener;


	private AppotaPayment ap;
//	private AlertDialogManager am;
	private MyReceiver receiver;
    private String apiKey = "bbbd977e1fccd70633a6b35ae1680a58052176e87";
    private String sandboxApiKey = "62b710613c47ff11db9ff884377577b2052176e87";
    private String url = "http://zegome.com/service/index/charge-money";
    
	
	private int mAction = -1;
	
	private boolean isPause = false;
	static final boolean UPLOAD_IMAGE = true;
	private boolean pendingPublishReauthorization = false;
	

	
	// ===========================================================
	// Methods for/from SuperClass/Interfaces
	// ===========================================================
	@Override
	public FrameLayout initView() {		
		setContentView(R.layout.main_layout);
	    return (FrameLayout) findViewById(R.id.root_view);
	}

	@Override
	public FrameLayout initGameView() {
		// TODO Auto-generated method stub
		return (FrameLayout) findViewById(R.id.game_view);
	}
	
	@Override
	public FrameLayout initAdViewLayout() {
		return (FrameLayout) findViewById(R.id.admob_view);
	}
	
	@Override
	public AndroidApplicationConfiguration config() {
		final AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
		config.useGL20 = true;
		config.useWakelock = true;
		return config;
	}
	
	@Override
	public void onComplete(final Bundle savedInstanceState) {
	
		((GomeController)mGameController).ctr = new Center();
		((GomeController)mGameController).ctr.controller = (GomeController) mGameController;
		((GomeController)mGameController).ctr.androidHelper.activity = this;
		((GomeController)mGameController).ctr.d.mFile = new ExternalFileEncrypt(this, "data", "data");

		mSmsNumber = D.isTestVersion ? SMS_TEST_NUMBER : SMS_NUMBER;
		
		((GomeController)mGameController).ctr.androidHelper.admobControl = new AdmobControl() {
			
			@Override
			public void show() {
						handler.post(new Runnable() {
							
							@Override
							public void run() {
								// TODO Auto-generated method stub
								if(isAdmob)
									mAdView.setVisibility(View.VISIBLE);
							}
						});
				
			}
			
			@Override
			public void hide() {
				// TODO Auto-generated method stub
				handler.post(new Runnable() {
					
					@Override
					public void run() {
						// TODO Auto-generated method stub
						if(isAdmob)
							mAdView.setVisibility(View.GONE);
					}
				});
			}
			
			@Override
			public void refresh() {
				// TODO Auto-generated method stub
				handler.post(new Runnable() {
					
					@Override
					public void run() {
						// TODO Auto-generated method stub
						if(isAdmob)
							mAdView.loadAd(new AdRequest());
					}					
				});
			}

			@Override
			public boolean isShow() {
				// TODO Auto-generated method stub
				if(isAdmob) {
					return (getAdView().isShown()==true);
				}
				return false;
			}

			@Override
			public boolean isHide() {
				// TODO Auto-generated method stub
				if(isAdmob) {
					return (getAdView().isShown()==false);
				}
				return false;
			}
		};
		//
//		try {
//		    PackageInfo info = MainActivity.this.getPackageManager().getPackageInfo(
//		          "com.zegome.game", PackageManager.GET_SIGNATURES);
//		    for (Signature signature : info.signatures) 
//		        {
//		           MessageDigest md = MessageDigest.getInstance("SHA");
//		           md.update(signature.toByteArray());
//		           Log.d("KeyHash:","key hash: " + Base64.encodeToString(md.digest(), Base64.DEFAULT));
//		        }
//		    }
//		 catch (NameNotFoundException e) {
//		} catch (NoSuchAlgorithmException e) {
//		}
//		
		mUiLifecycleHelper = new UiLifecycleHelper(this, mCallback);
		mUiLifecycleHelper.onCreate(savedInstanceState);
		
		mCustomLogin = new CustomLogin(MainActivity.this);
		
		// Check for an incoming notification. Save the info
        Uri intentUri = getIntent().getData();
        if (intentUri != null) {
        	String requestIdParam = intentUri.getQueryParameter("request_ids");
            if (requestIdParam != null) {
            	String array[] = requestIdParam.split(",");
                mRequestId = array[0];
            }
        }
        
        if (savedInstanceState != null) {
			pendingPublishReauthorization = savedInstanceState.getBoolean(PENDING_PUBLISH_KEY, false);
		}
                
        // Appota
		mSmsCreate = new SmsCreate(this, this);
		
		ap = AppotaPayment.getInstance();
		ap.setContext(this, apiKey, sandboxApiKey);
//		am = new AlertDialogManager(this);
		
		receiver = new MyReceiver();
		IntentFilter filter = new IntentFilter();
		filter.addAction(AppotaAction.SMS_PAYMENT_SUCCESS_ACTION);
		filter.addAction(AppotaAction.BANK_PAYMENT_SUCCESS_ACTION);
		filter.addAction(AppotaAction.CARD_PAYMENT_SUCCESS_ACTION);
		filter.addAction(AppotaAction.PAYPAL_PAYMENT_SUCCESS_ACTION);
		registerReceiver(receiver, filter);
	}
	
	
	@Override
	protected void onStart() {
		// TODO Auto-generated method stub
		super.onStart();
		if (dialog != null) {
			showDialogWithoutNotificationBar(dialogAction, dialogParams);
		}
	}
	
	@Override
	protected void onStop() {
		// TODO Auto-generated method stub
		super.onStop();
		if (dialog != null) {
			dialog.dismiss();
		}
	}
	
	@Override
	protected void onResume() {
		// TODO Auto-generated method stub
		super.onResume();
				
		isPause = false;
		dismissProgressDialog();
		mUiLifecycleHelper.onResume();	
	}	
		
	@Override
	protected void onPause() {
		// TODO Auto-generated method stub
		super.onPause();
		isPause = true;
		mUiLifecycleHelper.onPause();
	}
	
	@Override
	protected void onSaveInstanceState(Bundle outState) {
		// TODO Auto-generated method stub
		super.onSaveInstanceState(outState);
        outState.putBoolean(PENDING_PUBLISH_KEY, pendingPublishReauthorization);
        mUiLifecycleHelper.onSaveInstanceState(outState);
	}
	
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		// TODO Auto-generated method stub
		super.onActivityResult(requestCode, resultCode, data);
		mUiLifecycleHelper.onActivityResult(requestCode, resultCode, data);		
	}
	
	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		mUiLifecycleHelper.onDestroy();
		
		unregisterReceiver(receiver);
	}


	@Override
	public AndroidGameController initController() {
		// TODO Auto-generated method stub
		return new GomeController(this,this,this,this);
	}
	
	@Override
	public boolean isAdView() {
		// TODO Auto-generated method stub
		return isAdmob;
	}

	@Override
	public boolean isMC() {
		// TODO Auto-generated method stub
		return isMC;
	}

	@Override
	public boolean isKeyBoard() {
		// TODO Auto-generated method stub
		return true;
	}


	@Override
	public int keyboardLayoutId() {
		// TODO Auto-generated method stub
		return R.layout.keyboard_layout;
	}

	@Override
	public int editTextId() {
		// TODO Auto-generated method stub
		return R.id.edit;
	}
    
	
	@Override
	public String initAVId() {
		// TODO Auto-generated method stub
		return isGooglePlay ? GOOGLE_AD : APPOTA_AD;
	}

	@Override
	public String initMCId() {
		// TODO Auto-generated method stub
		return "49OBWVNLWMJNI7NGQJCLLENMB85UC";
	}

	@Override
	public String initAppPackage() {
		// TODO Auto-generated method stub
		return "gome_story";
	}

	@Override
	public String initPrefName() {
		// TODO Auto-generated method stub
		return "data";
	}

	//************************ FACEBOOK LISTENER ************************//
	
	@Override
	public void onLogin(final IFacebookProcessorListener processorListener) {
		// TODO Auto-generated method stub
		mFBProcessorListener = processorListener;
		mAction = IFacebookProcessorListener.LOGIN;
		handler.post(new Runnable() {
			
			@Override
			public void run() {
				// TODO Auto-generated method stub
//				progressDialog = ProgressDialog.show(MainActivity.this, "", MainActivity.this.getResources().getString(R.string.progress_dialog_login_text), true);

				mCustomLogin.onClick();
				
				onShowToast("onLogin");
			}
		});
	}
	
	//************************ APPOTA PAYMENT LISTENER ************************//

	@Override
	public void callSmsPurchase(ISmsProcessor processor) {
		
		mSmsProcessor = processor;
		handler.post(new Runnable() {

			@Override
			public void run() {
				String target = ((GomeController)mGameController).ctr.d.name;
				if (target == null) {
					target = "";
				}
				
				if (!isGooglePlay) {
					mSmsCreate.prepareSms(true);
					mSmsCreate.sendSMS(mSmsNumber, SMS_MESSAGE);
				} else {
					final int price = D.isTestVersion ? 500 : 15000;
					ap.makeSMSPayment(price, "", target, url, "Zegome Payment", "15000 -> 16500 Zegome gold", new TransactionStatusCallback() {
						
						@Override
						public void onTransactionSuccess(TransactionResult trans) {
							// TODO Auto-generated method stub
//							am.showPositiveDialog("Success", result.toString(), null);
							mSmsProcessor.onSendSMSSuccess();
//							if (mAppotaPaymentProcessor != null) {
//								mAppotaPaymentProcessor.onTransactionSuccess(trans.getErrorMessage(), trans.getAmount(), trans.getCurrency(), trans.getErrorCode());
//								mAppotaPaymentProcessor = null;
//							}
						}
						
						@Override
						public void onTransactionError(String message) {
							// TODO Auto-generated method stub
//							am.showPositiveDialog("Error", message, null);
							mSmsProcessor.onSendSMSFailure();
//							if (mAppotaPaymentProcessor != null) {
//								mAppotaPaymentProcessor.onTransactionError(0, message);
//								mAppotaPaymentProcessor = null;
//							}
						}
					});
				}
			}
		});
	}

	@Override
	public void callBankPurchase(IAppotaPaymentProcessorListener processor) {
		// TODO Auto-generated method stub
		mAppotaPaymentProcessor = processor;
		handler.post(new Runnable() {

			@Override
			public void run() {
				String target = ((GomeController)mGameController).ctr.d.name;
				
				if (target == null) {
					target = "";
				}
				
				
				int[] amounts = new int[] {20000, 50000, 100000};
				ap.makeBankPayment(amounts, url, "", target, "Zegome Payment", "20000 -> 22000 zegome gold \n50000 -> 55000 zegome gold \n100000 -> 110000 zegome gold");
			}
		});
	}

	@Override
	public void callPaypalPurchase(IAppotaPaymentProcessorListener processor) {
		// TODO Auto-generated method stub
		mAppotaPaymentProcessor = processor;
		handler.post(new Runnable() {

			@Override
			public void run() {
				String target = ((GomeController)mGameController).ctr.d.name;
				
				if (target == null) {
					target = "";
				}
				
				double[] amounts = new double[] {1, 2, 5};
				ap.makePaypalPayment(amounts, url, "", target, "Zegome Payment", "1$ -> 22000 zegome gold \n 2$ -> 44000 zegome gold \n 5$ -> 110000 zegome gold");
			}
		});
	}

	@Override
	public void callCardPurchase(IAppotaPaymentProcessorListener processor) {
		// TODO Auto-generated method stub
		mAppotaPaymentProcessor = processor;
		handler.post(new Runnable() {

			@Override
			public void run() {
				String target = ((GomeController)mGameController).ctr.d.name;
				
				if (target == null) {
					target = "";
				}
				
				ap.makeCardPayment("Zegome Payment", "10000 -> 11000 zegome gold \n20000 -> 22000 zegome gold \n50000 -> 55000 zegome gold", url, "", target);
			}
		});
	}

	@Override
	public void callSmsAuto(ISmsProcessor processor) {
		// TODO Auto-generated method stub
		mSmsProcessor = processor;
		handler.post(new Runnable() {

			@Override
			public void run() {
				String target = ((GomeController)mGameController).ctr.d.name;
				
				if (target == null) {
					target = "";
				}
				
//				mSmsCreate.prepareSms(true);
//				mSmsCreate.sendSMS(mSmsNumber, SMS_MESSAGE);
				if (!isGooglePlay) {
					mSmsCreate.prepareSms(true);
					mSmsCreate.sendSMS(mSmsNumber, SMS_MESSAGE);
				} else {
					final int price = D.isTestVersion ? 500 : 15000;
					ap.makeSMSPayment(price, "", target, url, "Zegome Payment", "15000 -> 16500 Zegome gold", new TransactionStatusCallback() {
						
						@Override
						public void onTransactionSuccess(TransactionResult trans) {
							// TODO Auto-generated method stub
//							am.showPositiveDialog("Success", result.toString(), null);
							mSmsProcessor.onSendSMSSuccess();
//							if (mAppotaPaymentProcessor != null) {
//								mAppotaPaymentProcessor.onTransactionSuccess(trans.getErrorMessage(), trans.getAmount(), trans.getCurrency(), trans.getErrorCode());
//								mAppotaPaymentProcessor = null;
//							}
						}
						
						@Override
						public void onTransactionError(String message) {
							// TODO Auto-generated method stub
//							am.showPositiveDialog("Error", message, null);
							mSmsProcessor.onSendSMSFailure();
//							if (mAppotaPaymentProcessor != null) {
//								mAppotaPaymentProcessor.onTransactionError(0, message);
//								mAppotaPaymentProcessor = null;
//							}
						}
					});
				}
			}
		});
	}
	@Override
	public void onSendSMSSuccess() {
		// TODO Auto-generated method stub
		if (mAppotaPaymentProcessor == null) {
			onShowToast("Sms success");
		}
		mSmsProcessor.onSendSMSSuccess();
	}

	@Override
	public void onSendSMSFailure() {
		// TODO Auto-generated method stub
		if (mSmsProcessor == null) {
			onShowToast("Sms failure");
		}
		mSmsProcessor.onSendSMSFailure();
	}

	@Override
	public void onSmsAutoSuccess() {
		// TODO Auto-generated method stub
		if (mSmsProcessor == null) {
			onShowToast("Sms success");
		}
		mSmsProcessor.onSmsAutoSuccess();
	}

	@Override
	public void onSmsAutoError() {
		// TODO Auto-generated method stub
		if (mSmsProcessor == null) {
			onShowToast("Sms failure");
		}
		mSmsProcessor.onSmsAutoError();
	}

	//************************ GOOGLE PAYMENT LISTENER ************************//
	
	// ===========================================================
	// Methods
	// ===========================================================
	
	//************************ FACEBOOK PROCESS ************************//
	
	private void sendFilteredRequest(final String link, final String message, final String data) {
		
		// Get a list of the user's friends' names and devices
		final Session session = Session.getActiveSession();
		Request friendDevicesGraphPathRequest = Request.newGraphPathRequest(session, "me/friends", new Request.Callback() {
			@Override
			public void onCompleted(Response response) {
				
				FacebookRequestError error = response.getError();
				if (error != null) {
//					Log.e(FriendSmashApplication.TAG, error.toString());
//					((HomeActivity)getActivity()).handleError(error, false);
				} else if (session == Session.getActiveSession()) {
					if (response != null) {
						// Get the result
						GraphObject graphObject = response.getGraphObject();
						JSONArray dataArray = (JSONArray)graphObject.getProperty("data");
						
						if (dataArray.length() > 0) {
							// Ensure the user has at least one friend ...
							
							// Store the filtered friend ids in the following List
							ArrayList<String> filteredFriendIDs = new ArrayList<String>();
							
							for (int i=0; i<dataArray.length(); i++) {
								JSONObject currentUser = dataArray.optJSONObject(i);
								if (currentUser != null) {
									JSONArray currentUserDevices = currentUser.optJSONArray("devices");
									if (currentUserDevices != null) {
										// The user has at least one (mobile) device logged into Facebook
										for (int j=0; j<currentUserDevices.length(); j++) {
											JSONObject currentUserDevice = currentUserDevices.optJSONObject(j);
											if (currentUserDevice != null) {
												String currentUserDeviceOS = currentUserDevice.optString("os");
												if (currentUserDeviceOS != null) {
													if (currentUserDeviceOS.equals("Android")) {
														filteredFriendIDs.add(currentUser.optString("id"));
													}
												}
											}
										}
									}
								}
							}
							
							// Now we have a list of friends with an Android device, we can send requests to them
					    	Bundle params = new Bundle();
					    	
					    	// Uncomment following link once uploaded on Google Play for deep linking
					    	if (link != null)
					    		params.putString("link", link);
					    	
					    	// We create our parameter dictionary as we did before
					    	if (message != null)
					    		params.putString("message", message);
					    	else
					    		params.putString("message", "Come on, my friend! This game is wonderful.");
					    	   
					    	if (data != null) {
					    		params.putString("data", data);
					    	}
					    	
					    	// Of course, not all of our suggested friends will have Android devices - we need to filter them down
					    	ArrayList<String> validSuggestedFriends = new ArrayList<String>();
		             
		                    // So, we loop through each suggested friend
		                    for (String suggestedFriend : filteredFriendIDs)
		                    {
		                        // If they are on our device filtered list, we know they have an Android device
//		                        if (filteredFriendIDs.contains(suggestedFriend))
		                        {
		                            // So we can call them valid
		                        	validSuggestedFriends.add(suggestedFriend);
		                        }
		                    }
		                    params.putString("suggestions", TextUtils.join(",", validSuggestedFriends.toArray(new String[validSuggestedFriends.size()])));
							    	
					    	// Show FBDialog without a notification bar
					    	showDialogWithoutNotificationBar("apprequests", params);
						}
					}
				}
			}
		});
		// Pass in the fields as extra parameters, then execute the Request
		Bundle extraParamsBundle = new Bundle();
		extraParamsBundle.putString("fields", "name,devices");
		friendDevicesGraphPathRequest.setParameters(extraParamsBundle);
		Request.executeBatchAsync(friendDevicesGraphPathRequest);
	}
	
	
	private void getRequestData(final String inRequestId) {
	     // Create a new request for an HTTP GET with the
	     // request ID as the Graph path.
	  final Center center = ((GomeController)mGameController).ctr;
	  
	     Request request = new Request(Session.getActiveSession(), 
	       inRequestId, null, HttpMethod.GET, new Request.Callback() {
	     
	     @Override
	     public void onCompleted(Response response) {
	      // Process the returned response
	      GraphObject graphObject = response.getGraphObject();
	      FacebookRequestError error = response.getError();
	                     boolean processError = false;
	                     // Default message
	                     String message = "Incoming request";
	                     if (graphObject != null) {
	                      // Check if there is extra data
	                      if (graphObject.getProperty("data") != null) {
	                       try {
	                        // Get the data, parse info to get the key/value info
	                        JSONObject dataObject = new JSONObject((String)graphObject.getProperty("data"));
	                        // Get the value for the key - diamond
	                        String diamond = dataObject.getString("diamond");
	                                 // Get the sender's name
	                                 JSONObject fromObject = (JSONObject) graphObject.getProperty("from");
	                                 String sender = fromObject.getString("name");
	                                 
	                                 center.mGiftRequests.add(new GiftRequest(sender, "kim cuong", Integer.valueOf(diamond)));
	                                 
	                                 String title = sender+" sent you a gift";
	                                 // Create the text for the alert based on the sender
	                                 // and the data
	                                 message = title + "\n\n" + 
	                                 "diamond: "+ diamond;
//	                                 + " Karma: "+ karma ;
	                       } catch (JSONException e) {
	                        processError = true;
	                        message = "Error getting request info";
	                       }
	                      } else if (error != null) {
	                       processError = true;
	                       message = "Error getting request info";
	                      }
	                     }
	                     Toast.makeText(MainActivity.this, message, Toast.LENGTH_LONG).show();
	                     if (!processError) {
	                      deleteRequest(inRequestId);
	                     }

	     }
	    });
	     // Execute the request asynchronously.
	     Request.executeBatchAsync(request);
	    }
	
	
	private void deleteRequest(String inRequestId) {
	    	// Create a new request for an HTTP delete with the
	    	// request ID as the Graph path.
	    	Request request = new Request(Session.getActiveSession(), 
	    			inRequestId, null, HttpMethod.DELETE, new Request.Callback() {
						
						@Override
						public void onCompleted(Response response) {
							// Show a confirmation of the deletion
							// when the API call completes successfully.
							Toast.makeText(MainActivity.this, "Request deleted",
			                        Toast.LENGTH_SHORT).show();
						}
					});
	    	// Execute the request asynchronously.
	    	Request.executeBatchAsync(request);
	    }


	private void showDialogWithoutNotificationBar(final String action, final Bundle params) {
			// Create the dialog
			
			if (params == null) {
				return;
			}
			handler.post(new Runnable() {

				@Override
				public void run() {
					// TODO Auto-generated method stub
					dialog = new WebDialog.Builder(MainActivity.this, Session.getActiveSession(), action, params).setOnCompleteListener(
									new WebDialog.OnCompleteListener() {

										@Override
										public void onComplete(Bundle values, FacebookException error) {
											String message = null;
											if (error != null) {
												
												if (error instanceof FacebookOperationCanceledException) {
													message = action + "FacebookOperationCanceledException";
												} else {
													message = action + getResources().getString(R.string.network_error);
													showError(getResources().getString(R.string.network_error), false);
												}
												if (mFBProcessorListener != null) {
			        								mFBProcessorListener.onFailure(message);
			        								mFBProcessorListener = null;
			        							}
											} else {
												if (mFBProcessorListener != null) {
													message = action + "complete";
			        								mFBProcessorListener.onComplete(message);
			        								mFBProcessorListener = null;
			        							}
											}
											
											dialog = null;
											dialogAction = null;
											dialogParams = null;
										}
									}).build();

					// Store the dialog information in attributes
					dialogAction = action;

					// Show the dialog
					dialog.show();
					
					
				}
			});

		}

		// Show user error message as a toast
	private void showError(String error, boolean logout) {
		Toast.makeText(this, error, Toast.LENGTH_LONG).show();
		if (logout) {
			logout();
		}
	}

	void handleError(FacebookRequestError error, boolean logout) {
	     DialogInterface.OnClickListener listener = null;
	     String dialogBody = null;

	     if (error == null) {
	        dialogBody = getString(R.string.error_dialog_default_text);
	     } else {
	        switch (error.getCategory()) {

	                case AUTHENTICATION_REOPEN_SESSION:
	                    // close the session and reopen it.
	                    dialogBody = getString(R.string.error_authentication_reopen);
	                    listener = new DialogInterface.OnClickListener() {
	                        @Override
	                        public void onClick(DialogInterface dialogInterface, int i) {
	                            Session session = Session.getActiveSession();
	                            if (session != null && !session.isClosed()) {
	                                session.closeAndClearTokenInformation();
	                            }
	                        }
	                    };
	                    break;

	                case SERVER:
	                case THROTTLING:
	                    // this is usually temporary, don't clear the fields, and
	                    // ask the user to try again
	                    dialogBody = getString(R.string.error_server);
	                    break;

	                case BAD_REQUEST:
	                    // this is likely a coding error, ask the user to file a bug
	                    dialogBody = getString(R.string.error_bad_request, error.getErrorMessage());
	                    break;

	                case CLIENT:
	                	// this is likely an IO error, so tell the user they have a network issue
	                	dialogBody = getString(R.string.network_error);
	                    break;
	                    
	                case OTHER:
	                default:
	                    // an unknown issue occurred, this could be a code error, or
	                    // a server side issue, log the issue, and either ask the
	                    // user to retry, or file a bug
	                    dialogBody = getString(R.string.error_unknown, error.getErrorMessage());
	                    break;
	            }
	        }

	        new AlertDialog.Builder(this)
	                .setPositiveButton(R.string.error_dialog_button_text, listener)
	                .setTitle(R.string.error_dialog_title)
	                .setMessage(dialogBody)
	                .show();
	        
	        if (logout) {
	        	logout();
	        }
	}
		
		
	private void logout() {
		Session.getActiveSession().closeAndClearTokenInformation();
	}

	private boolean ensureOpenSession() {
		if (Session.getActiveSession() == null || !Session.getActiveSession().isOpened()) {
				
			Session.openActiveSession(this, true, new Session.StatusCallback() {
				@Override
				public void call(Session session, SessionState state, Exception exception) {
					onSessionStateChange(session, state, exception);
				}
			});
			return false;
		}
			return true;
	}
	
	void log(final String message) {
		Log.e("GomeStoryActivity", message);
	}
	
	private void onSessionStateChange(Session session, SessionState state, Exception exception) {
		if (state.isOpened() && mRequestId != null) {
    		getRequestData(mRequestId);
    		mRequestId = null;
    	}
		
	    if (state.isOpened()) {
        	onUpdateView(true);
	    	
            if (pendingPublishReauthorization && 
            		state.equals(SessionState.OPENED_TOKEN_UPDATED)) {
            	pendingPublishReauthorization = false;
            	publishStory(bitmap);
            }
	    } else if (state.isClosed()) {
	    	onUpdateView(false);
	    }
	    
	}	
	
	private void onUpdateView(final boolean flag) {
		log("updateView flag = "+flag);
		if (flag) {
			if (mFBProcessorListener != null && mAction == IFacebookProcessorListener.LOGIN) {
				mFBProcessorListener.onComplete("");
				mFBProcessorListener = null;
			}
		} else {
			if (mFBProcessorListener != null && mAction == IFacebookProcessorListener.LOGIN) {
				mFBProcessorListener.onFailure("");
				mFBProcessorListener = null;
			}
		}
	}
	
	/*
	 * Helper method to check a collection for a string.
	 */
	private boolean isSubsetOf(Collection<String> subset, Collection<String> superset) {
	    for (String string : subset) {
	        if (!superset.contains(string)) {
	            return false;
	        }
	    }
	    return true;
	}
	
	/*
	 * Helper method to dismiss the progress dialog.
	 */
	private void dismissProgressDialog() {
		// Dismiss the progress dialog
		if (progressDialog != null) {
            progressDialog.dismiss();
            progressDialog = null;
        }
	}
	
	/*
	 * Method to publish a story.
	 */
	private void publishStory(final Bitmap image) {
		// Un-comment the line below to turn on debugging of requests
//		Settings.addLoggingBehavior(LoggingBehavior.REQUESTS);
		
		Request.newUploadPhotoRequest(Session.getActiveSession(), image, new Callback() {
			
			@Override
			public void onCompleted(Response response) {
				// TODO Auto-generated method stub
				
			}
		}).executeAsync();
		
	    Session session = Session.getActiveSession();
	    if (session != null) {
		    List<String> permissions = session.getPermissions();
		    if (!isSubsetOf(PERMISSIONS, permissions)) {
		    	pendingPublishReauthorization = true;
		    	Session.NewPermissionsRequest newPermissionsRequest = new Session 
		    	.NewPermissionsRequest(this, PERMISSIONS);
		    	session.requestNewPublishPermissions(newPermissionsRequest);
		    	return;
		    }
		    
	        progressDialog = ProgressDialog.show(MainActivity.this, "", MainActivity.this.getResources().getString(R.string.progress_dialog_sharing_text), true);
	        
		    try {
				RequestBatch requestBatch = new RequestBatch();
				if (UPLOAD_IMAGE) {
					Bundle imageParams = new Bundle();
					imageParams.putParcelable("file", image);
					
				    Request.Callback imageCallback = new Request.Callback() {

						@Override
						public void onCompleted(Response response) {
							FacebookRequestError error = response.getError();
							if (error != null) {
								dismissProgressDialog();
							}
						}
				    };
				    
					Request imageRequest = new Request(Session.getActiveSession(), "me/staging_resources", imageParams, HttpMethod.POST, imageCallback);
					
					imageRequest.setBatchEntryName("imageUpload");
					
					requestBatch.add(imageRequest);
				}
								
				JSONObject picture = new JSONObject();
				
				if (UPLOAD_IMAGE) {
					picture.put("image", "{result=imageUpload:$.uri}");
				} else {
					picture.put("image", "http://farm4.staticflickr.com/3667/10670849985_85d29674a1_o.png");
				}				
				picture.put("title", "A Picture of GomeStory");			
				picture.put("url", "http://zegome.com/gomestory");
				picture.put("description", "Một sự sáng tạo thú vị của tôi");
				
				// Set up object request parameters
				Bundle objectParams = new Bundle();
				objectParams.putString("object", picture.toString());
			    Request.Callback objectCallback = new Request.Callback() {

					@Override
					public void onCompleted(Response response) {
						FacebookRequestError error = response.getError();
						if (error != null) {
							dismissProgressDialog();
						}
					}
			    };
			    
			    Request objectRequest = new Request(Session.getActiveSession(), "me/objects/gome_story:picture", objectParams, 
		                HttpMethod.POST, objectCallback);
				
				objectRequest.setBatchEntryName("objectCreate");
				
				// Add the request to the batch
				requestBatch.add(objectRequest);
				
				Bundle actionParams = new Bundle();
				// Refer to the "id" in the result from the previous batch request
				actionParams.putString("picture", "{result=objectCreate:$.id}");
				// Turn on the explicit share flag
//				actionParams.putString("fb:explicitly_shared", "true");
				
				// Set up the action request callback
				Request.Callback actionCallback = new Request.Callback() {

					@Override
					public void onCompleted(Response response) {
						dismissProgressDialog();
						FacebookRequestError error = response.getError();
						if (error != null) {
							Toast.makeText(MainActivity.this
								.getApplicationContext(),
								error.getErrorMessage(),
								Toast.LENGTH_LONG).show();
						} else {
//							String actionId = null;
//							try {
//								JSONObject graphResponse = response
//				                .getGraphObject()
//				                .getInnerJSONObject();
//								actionId = graphResponse.getString("id");
//							} catch (JSONException e) {
//								Log.i(TAG, "JSON error "+ e.getMessage());
//							}
//							Toast.makeText(MainActivity.this.getApplicationContext(), actionId,
//								Toast.LENGTH_LONG).show();
						}
					}
				};
				
				// Create the publish action request
				Request actionRequest = new Request(Session.getActiveSession(),
						"me/gome_story:draw", actionParams, HttpMethod.POST, actionCallback);
				
				// Add the request to the batch
				requestBatch.add(actionRequest);
				
				// Execute the batch request
				requestBatch.executeAsync();
				
				if (mFBProcessorListener != null) {
					mFBProcessorListener.onComplete("publish story success");
					mFBProcessorListener = null;
				}
				
			} catch (JSONException e) {
				if (mFBProcessorListener != null) {
					mFBProcessorListener.onFailure("publish story failure");
					mFBProcessorListener = null;
				}
				dismissProgressDialog();
			}
		}
	    
	    bitmap = null;
	}

	@Override
	public void onNewsFeed(final IFacebookProcessorListener processorListener, String link, String name, String caption, String descript, String pictureUrl) {
		mFBProcessorListener = processorListener;
		
		final Bundle params = new Bundle();
		params.putString("name", name);
		params.putString("message", "GomeStory");
		params.putString("caption", caption);
		params.putString("description", descript);
		params.putString("link", link);
		params.putString("picture", pictureUrl);
		
		dialogParams = params;
		if (ensureOpenSession()) {
			showDialogWithoutNotificationBar("feed", dialogParams);
		}
	}
	
	private WebDialog dialog = null;
	private String dialogAction = null;
	private Bundle dialogParams = null;
	private Bitmap bitmap = null;
	
	@Override
	public void onOpenAction(IFacebookProcessorListener processorListener, final Bitmap image) {
		mAction = IFacebookProcessorListener.PUBLISH_STORY;
		mFBProcessorListener = processorListener;
		handler.post(new Runnable() {
			
			@Override
			public void run() {
				bitmap = image;
				publishStory(bitmap);
			}
		});
	}
	
	@Override
	public void onSendRequest(IFacebookProcessorListener processorListener, final String link, final String message, final String data, final boolean isFilter) {
		// TODO Auto-generated method stub
		mAction = IFacebookProcessorListener.SEND_REQUEST;
		mFBProcessorListener = processorListener;
		handler.post(new Runnable() {
			
			@Override
			public void run() {
				if (ensureOpenSession()) {
					sendFilteredRequest(link, message, data);
				}
			}
		});
	}

	//************************ APPOTA PAYMENT PROCESS ************************//

	public class MyReceiver extends AppotaPaymentReceiver {

		@Override
		public void onBankPaymentSuccess(TransactionResult trans) {
			Toast.makeText(MainActivity.this, trans.toString(), Toast.LENGTH_SHORT).show();
			
			if (mAppotaPaymentProcessor != null) {
				mAppotaPaymentProcessor.onTransactionSuccess(trans.getErrorMessage(), trans.getAmount(), trans.getCurrency(), trans.getErrorCode());
				mAppotaPaymentProcessor = null;
			}
		}

		@Override
		public void onSMSPaymentSuccess(TransactionResult trans) {
			Toast.makeText(MainActivity.this, trans.toString(), Toast.LENGTH_SHORT).show();
			if (mAppotaPaymentProcessor != null) {
				mAppotaPaymentProcessor.onTransactionSuccess(trans.getErrorMessage(), trans.getAmount(), trans.getCurrency(), trans.getErrorCode());
				mAppotaPaymentProcessor = null;
			}
		}

		@Override
		public void onCardPaymentSuccess(CardPaymentResult trans) {
			Toast.makeText(MainActivity.this, trans.toString(), Toast.LENGTH_SHORT).show();
			if (mAppotaPaymentProcessor != null) {
				mAppotaPaymentProcessor.onTransactionSuccess(trans.getErrorMessage(), String.valueOf(trans.getAmount()), trans.getCurrency(), trans.getErrorCode());
				mAppotaPaymentProcessor = null;
			}
		}

		@Override
		public void onPaypalPaymentSuccess(TransactionResult trans) {
			Toast.makeText(MainActivity.this, trans.toString(), Toast.LENGTH_SHORT).show();
			if (mAppotaPaymentProcessor != null) {
				mAppotaPaymentProcessor.onTransactionSuccess(trans.getErrorMessage(), trans.getAmount(), trans.getCurrency(), trans.getErrorCode());
				mAppotaPaymentProcessor = null;
			}
		}

        @Override
        public void onGooglePaymentSuccess(TransactionResult result) {
            Toast.makeText(MainActivity.this, result.toString(), Toast.LENGTH_SHORT).show();
        }

    }

	
}